package com.alander.nexusgo.user.utils;

import jakarta.servlet.http.HttpServletRequest;

import java.util.regex.Pattern;

public class IpUtil {

    // 正则表达式，用于验证IPv4和IPv6地址
    private static final Pattern IPV4_PATTERN = Pattern.compile(
            "^(\\d{1,3}\\.){3}\\d{1,3}$");
    private static final Pattern IPV6_PATTERN = Pattern.compile(
            "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]|[0-9]){1})\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]|[0-9]){1})|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]|[0-9]){1})\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]|[0-9]){1}))$");

    /**
     * 获取请求客户端的IPv4地址（如果存在）
     *
     * @param request HttpServletRequest对象
     * @return 客户端IPv4地址，如果不存在则返回null
     */
    public static String getClientIpv4(HttpServletRequest request) {
        String ipAddress = getClientIp(request);
        if (IPV4_PATTERN.matcher(ipAddress).matches()) {
            return ipAddress;
        }
        return null;
    }

    /**
     * 获取请求客户端的IPv6地址（如果存在）
     *
     * @param request HttpServletRequest对象
     * @return 客户端IPv6地址，如果不存在则返回null
     */
    public static String getClientIpv6(HttpServletRequest request) {
        String ipAddress = getClientIp(request);
        if (IPV6_PATTERN.matcher(ipAddress).matches()) {
            return ipAddress;
        }
        return null;
    }

    /**
     * 获取请求客户端的IP地址（优先从请求头中获取，如果不可用则使用getRemoteAddr()）
     *
     * @param request HttpServletRequest对象
     * @return 客户端IP地址
     */
    public static String getClientIp(HttpServletRequest request) {
        // 尝试从X-Forwarded-For请求头中获取IP地址（可能包含多个IP，取第一个）
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress != null && !ipAddress.isEmpty() && !"unknown".equalsIgnoreCase(ipAddress)) {
            if (ipAddress.contains(",")) {
                ipAddress = ipAddress.split(",")[0];
            }
        } else {
            // 如果X-Forwarded-For不可用，则尝试其他请求头，最后使用getRemoteAddr()
            ipAddress = request.getHeader("Proxy-Client-IP");
            if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
                if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
                    ipAddress = request.getHeader("HTTP_CLIENT_IP");
                    if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
                        ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
                        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
                            ipAddress = request.getRemoteAddr();
                        }
                    }
                }
            }
        }
        return ipAddress;
    }
}
